<?php
if (!class_exists('CPT_columns')){

    class CPT_columns{
        /**
         * $cpt_columns
         *
         * holds columns
         * @var array
         */
        public $cpt_columns = array();
        /**
         * $cpt_remove_columns
         *
         * holds columns to be removed
         * @var array
         */
        public $cpt_remove_columns = array();
        /**
         * $cpt_sortable_columns
         *
         * holds sortable columns
         * @var array
         */
        public $cpt_sortable_columns = array();
        /**
         * $cpt_name
         *
         * Holds custom post type name
         * @var string
         */
        public $cpt_name = '';
        /**
         * $replace
         *
         * Should coulmns be replace (true) or added (false)
         * @var boolean
         */
        public $replace = false;
        /**
         * __construct
         *
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param string  $cpt     custom post type name
         * @param boolean $replace (optional) replace or add
         */
        function __construct($cpt = '', $replace = false){
            $this->cpt_name = $cpt;
            $this->replace = $replace;
            //add columns
            add_filter( "manage_{$cpt}_posts_columns", array($this,'_cpt_columns' ),50);
            //remove columns
            add_filter( "manage_{$cpt}_posts_columns", array($this,'_cpt_columns_remove' ),60);
            //display columns
            add_action("manage_{$cpt}_posts_custom_column", array($this,'_cpt_custom_column'), 50, 2);
            //sortable columns
            add_filter( "manage_edit-{$cpt}_sortable_columns", array($this,"_sortable_columns" ),50);
            //sort order
            add_filter( 'pre_get_posts',array($this, '_column_orderby' ),50);
        }
 
        /**
         * _cpt_columns
         *
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  array $defaults
         * @return array
         */
        function _cpt_columns($defaults){
            global $typenow;
            if ($this->cpt_name == $typenow){
                $tmp = array();
                foreach ($this->cpt_columns as $key => $args) {
                    $tmp[$key] = $args['label'];
                }
                if ($this->replace)
                    return $tmp;
                else
                    $defaults = array_merge($defaults,$tmp);
            }
             
            return $defaults;
        }
 
        /**
         * _cpt_columns_remove
         *
         * used to remove columns
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  array $columns
         * @return array        
         */
        function _cpt_columns_remove($columns){
            foreach ($this->cpt_remove_columns as $key) {
                if (isset($columns[$key]))
                    unset($columns[$key]);
            }
            return $columns;
        }
        /**
         * _sortable_columns
         *
         * sets sortable columns
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  array $columns
         * @return array
         */
        function _sortable_columns($columns){
            global $typenow;
            if ($this->cpt_name == $typenow){
                foreach ($this->cpt_sortable_columns as $key => $args) {
                    $columns[$key] = $key;
                }
            }
            return $columns;
        }
        /**
         * _cpt_custom_column
         *
         * calls do_column() when the column is set
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  string $column_name column name
         * @param  int $post_id     post ID
         * @return void
         */
        function _cpt_custom_column($column_name, $post_id) {
            if(isset($this->cpt_columns[$column_name]))
                $this->do_column($post_id,$this->cpt_columns[$column_name],$column_name);
        }
 
        /**
         * do_column
         *
         * used to display the column
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  int $post_id         post ID
         * @param  array $column        column args
         * @param  string $column_name  column name
         * @return void
         */
        function do_column($post_id,$column,$column_name){
            if (in_array($column['type'],array('text','thumb','post_meta','custom_tax') ) )
                echo $column['prefix'];
            switch ($column['type']) {
                case 'text':
                    echo apply_filters( 'cpt_columns_text_'.$column_name, $column['text'],$post_id,$column, $column_name);
                    break;
                case 'thumb':
                    if (has_post_thumbnail( $post_id )){
                        the_post_thumbnail(  $column['size'] );
                    }else{
                        echo '<img src="'.get_bloginfo('template_url').'/images/placeholder.png" width="80" height="80" alt="no image"/>';
                    }
                    break;
                case 'post_meta':
                    echo get_post_meta($post_id,$column['meta_key'],true);
                    break;
                case 'custom_tax':
                    $post_type = get_post_type($post_id);
                    $terms = get_the_terms($post_id, $column['taxonomy']);
                    if ( !empty($terms) ) {
                        foreach ( $terms as $term ){
                            $href = "edit.php?post_type={$post_type}&{$column['taxonomy']}={$term->slug}";
                            $name = esc_html(sanitize_term_field('name', $term->name, $term->term_id, $column['taxonomy'], 'edit'));
                            $post_terms[] = "<a href='{$href}'>{$name}</a>";
                        }                          
                        echo join( ', ', $post_terms );
                    }
                    else echo '';
                    break;
            }//end switch
            if (in_array($column['type'],array('text','thumb','post_meta','custom_tax') ) )
                echo $column['suffix'];
        }//end do_column
 
        /**
         * _column_orderby
         *
         * used to roder by meta keys
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  object $query
         * @return void
         */
        function _column_orderby( $query ) {
            if( ! is_admin() ) 
                return;
 
            $orderby = $query->get( 'orderby');
            $keys = array_keys((array)$this->cpt_sortable_columns);
            if ( in_array($orderby,$keys) ) {
                //order by meta
                if ('post_meta' == $this->cpt_sortable_columns[$orderby]['type']){
                    $query->set('meta_key',$orderby);
                    $query->set('orderby',$this->cpt_sortable_columns[$orderby]['orderby']);
                }
            }
        }//end _column_orderby
 
        /**
         * add_column
         *
         * used to add column
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param string $key column id
         * @param array $args column arguments
         * @return void
         */
        function add_column($key,$args){
            $def = array(
                'label'    => 'column label',
                'size'     => array('80','80'),
                'taxonomy' => '',
                'meta_key' => '',
                'sortable' => false,
                'text'     => '',
                'type'     => 'native', //'native','post_meta','custom_tax',text
                'orderby'  => 'meta_value',
                'prefix'   => '',
                'suffix'   => ''
            );
            $this->cpt_columns[$key] = array_merge($def,$args);
 
            if ($this->cpt_columns[$key]['sortable'])
                $this->cpt_sortable_columns[$key] = $this->cpt_columns[$key];
        }//end add_column
 
        /**
         * remove_column
         *
         * Used to remove columns
         *
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  string $key column key to be removed
         * @return void
         */
        function remove_column($key){
            $this->cpt_remove_columns[] = $key;
        }//end remove_column
 
    }//end class
}//end if
 
/* usage:
//create an instace
$post_columns = new CPT_columns('post'); // if you want to replace and reorder columns then pass a second parameter as true
//add native column
$post_columns->add_column('title',
  array(
        'label'    => __('Title'),
        'type'     => 'native',
        'sortable' => true
    )
);
//add thumbnail column
$post_columns->add_column('post_thumb',
  array(
        'label' => __('Thumb'),
        'type'  => 'thumb',
        'size'  => array('80,80') //size accepted  by the_post_thumbnail as array or string
    )
);
//add taxonomy
$post_columns->add_column('custom_tax_id',
  array(
        'label'    => __('Custom Taxonomy'),
        'type'     => 'custom_tax',
        'taxonomy' => 'category' //taxonomy name
    )
);
//custom field column
$post_columns->add_column('price',
  array(
        'label'    => __('Custom Field'),
        'type'     => 'post_meta',
        'meta_key' => 'price', //meta_key
        'orderby' => 'meta_value', //meta_value,meta_value_num
        'sortable' => true,
        'prefix' => "$",
        'suffix' => ""
    )
);
//remove date column
$post_columns->remove_column('date');
*/
if (!class_exists('Tax_CTP_Filter')){
  /**
    * Tax CTP Filter Class 
    * Simple class to add custom taxonomy dropdown to a custom post type admin edit list
    * @author Ohad Raz <admin@bainternet.info>
    * @version 0.1
    */
    class Tax_CTP_Filter
    {
        /**
         * __construct 
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param array $cpt [description]
         */
        function __construct($cpt = array()){
            $this->cpt = $cpt;
            // Adding a Taxonomy Filter to Admin List for a Custom Post Type
            add_action( 'restrict_manage_posts', array($this,'my_restrict_manage_posts' ));
        }
  
        /**
         * my_restrict_manage_posts  add the slelect dropdown per taxonomy
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @return void
         */
        public function my_restrict_manage_posts() {
            // only display these taxonomy filters on desired custom post_type listings
            global $typenow;
            $types = array_keys($this->cpt);
            if (in_array($typenow, $types)) {
                // create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
                $filters = $this->cpt[$typenow];
                foreach ($filters as $tax_slug) {
                    // retrieve the taxonomy object
                    $tax_obj = get_taxonomy($tax_slug);
                    $tax_name = $tax_obj->labels->name;
  
                    // output html for taxonomy dropdown filter
                    echo "<select name='".strtolower($tax_slug)."' id='".strtolower($tax_slug)."' class='postform'>";
                    echo "<option value=''>Show All $tax_name</option>";
                    $this->generate_taxonomy_options($tax_slug,0,0,(isset($_GET[strtolower($tax_slug)])? $_GET[strtolower($tax_slug)] : null));
                    echo "</select>";
                }
            }
        }
         
        /**
         * generate_taxonomy_options generate dropdown
         * @author Ohad Raz <admin@bainternet.info>
         * @since 0.1
         * @param  string  $tax_slug 
         * @param  string  $parent   
         * @param  integer $level    
         * @param  string  $selected 
         * @return void            
         */
        public function generate_taxonomy_options($tax_slug, $parent = '', $level = 0,$selected = null) {
            $args = array('hide_empty' => false);
            if(!is_null($parent)) {
                $args = array('parent' => $parent,'hide_empty' => false);
            }
            $terms = get_terms($tax_slug,$args);
            $tab='';
            for($i=0;$i<$level;$i++){
                $tab.='--';
            }
  
            foreach ($terms as $term) {
                // output each select option line, check against the last $_GET to show the current option selected
                echo '<option value='. $term->slug, $selected == $term->slug ? ' selected="selected"' : '','>' .$tab. $term->name .' (' . $term->count .')</option>';
                $this->generate_taxonomy_options($tax_slug, $term->term_id, $level+1,$selected);
            }
  
        }
    }//end class
}//end if